﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.WebPages;

using ProjectBase.Core;
using ProjectBase.Core.Web;
using ProjectBase.Mvc;
using ProjectBase.Mvc.Controllers;

using $prjsn$.Common;

namespace $safeprojectname$.Controls
{
    public abstract class RazorControl<TModel> : WebViewPage<TModel>
        where TModel : class, ICoreModel
    {
        #region AddControls
        /// <summary>
        /// Adds controls on page
        /// </summary>
        /// <param name="controls"></param>
        /// <returns></returns>
        protected virtual HtmlString AddControls(params IVisualControl[] controls)
        {
            var holder = new PlaceHolder
            {
                ViewContext = ViewContext,
                ViewData = new ViewDataDictionary<ICoreModel>(Model),
                Url = Url,
                Html = Html,
            };

            holder.AddControls(controls);

            return new HtmlString(holder.ToHtmlString());
        }
        #endregion AddControls

        #region GetLocalized (prefered way on UI)
        /// <summary>
        ///     Returns Html.ENCODED string!
        ///     Translates provided "key" into user's currently selected language.
        ///     As the parameter "area" for Transaltor is used "ControllerName"
        /// </summary>
        /// <param name = "key">Searched key</param>
        /// <returns>Transalted value (or key if not found)</returns>
        protected virtual string GetLocalized(string key)
        {
            var webModel = Model as IViewModel;

            var area = webModel.Is()
                ? webModel.MasterModel.ControllerName
                : string.Empty;

            return key.GetLocalized(area);
        }
        #endregion GetLocalized

        #region IButtonItem -> Get Form 'Action' URL
        /// <summary>
        ///     Returns the Url for this button Form 'action'.
        ///     1) firstly test if there is filled 'button.FormActionUrl'
        ///     2) assembles the URL using UrlHelper, button.FormAction
        ///     and button or model controller
        /// </summary>
        /// <returns>URL for this button Form 'action' attribute</returns>
        protected virtual string GetFormActionUrl(IButtonItem button)
        {
            var controller = button.FormController;
            if (ProjectBase.Core.Ext.IsEmpty(controller))
            {
                var webModel = Model as IViewModel;
                if (webModel.Is())
                {
                    controller = webModel.MasterModel.ControllerName;
                }
            }
            return Url.Action(button.FormAction, controller, button.FormRouteValues);
        }

        #endregion IButtonItem -> Get Form 'Action' URL

        #region Form
        /// <summary>
        ///     Creates the starting FORM tag for sent 'submit' button.
        ///     1) Form 'action' attribute is filled using GetFormActionUrl(button) operation.
        ///     2) id="button.ButtonName" (can be evaluated by JavaScript)
        ///     3) enctype="multipart/form-data" allowing uploading files
        /// </summary>
        /// <param name = "button"></param>
        /// <returns></returns>
        public virtual HtmlString CreateForm(IButtonItem button)
        {
            var form = new StringBuilder();
            if (button.Is())
            {
                form.Append(
                    "<form action=\"{0}\" method=\"post\" enctype=\"multipart/form-data\" ".FormatWith(
                        GetFormActionUrl
                            (button)));
                if (button.FormIdForJS.IsNotEmpty())
                {
                    form.Append(" id=\"{0}\" name=\"{0}\" ".FormatWith(button.FormIdForJS));
                }
                form.Append(" >");
                form.Append(System.Web.Helpers.AntiForgery.GetHtml());
            }
            return new HtmlString(form.ToString());
        }

        /// <summary>
        ///     Renders the closing FORM tag for provided button.
        ///     Also sets the button.IsFormTagClosed = true (to be not rendered twice)
        ///     Also appends the submit button inside this form element,
        ///     which allows on some smart browsers use the HTML instead of the JS.
        /// </summary>
        /// <param name = "button"></param>
        /// <returns></returns>
        public virtual HtmlString CloseForm(IButtonItem button)
        {
            var form = new StringBuilder();
            if (button.Is()
                && !button.IsFormTagClosed)
            {
                if (button.FormIdForJS.IsNotEmpty()) // append the submit button with the 'ID' attribute set
                {
                    // to the button.FormIdForJS + "Submit"
                    form.Append(
                        "<input type=\"submit\" id=\"{0}Submit\" class=\"hidden\" />".FormatWith(
                            button.
                                FormIdForJS));
                }
                form.Append("</form>");
                button.IsFormTagClosed = true;
            }
            return new HtmlString(form.ToString());
        }
        #endregion Form

        #region RenderControl
        protected HelperResult RenderControl(string path, params object[] data)
        {
            var cpath = path.StartsWith(Str.WebControls.ControlsPath)
                     || path.StartsWith(Str.WebControls.ControlsPath2)
                      ? path
                      : Path.Combine(Constants.WebControls.ControlsPath, path.TrimStart('\\', '/'));
            return RenderPage(cpath, data);
        }
        #endregion RenderControl

        #region Url helper
        IUrlHelper _aopUrlHelper;
        public new virtual IUrlHelper Url
        {
            get
            {
                if (_aopUrlHelper.IsNull())
                {
                    _aopUrlHelper = new AopUrlHelper(base.Url.RequestContext, base.Url.RouteCollection);
                }
                return _aopUrlHelper;
            }
            set { _aopUrlHelper = value; }
        }
        #endregion Url helper

        #region Render Action
        public virtual MvcHtmlString RenderAction(string actionName, string controllerName = null, RouteValueDictionary routeValues = null)
        {
            return System.Web.Mvc.Html.ChildActionExtensions.Action(Html, actionName, controllerName, routeValues);
        }
        #endregion Render Action

        #region NOT Encoded
        protected virtual HtmlString X(string value)
        {
            return new HtmlString(value);
        }
        #endregion
    }
}